home *** CD-ROM | disk | FTP | other *** search
/ Java 1996 August / Java - Summer 1996.iso / kaffe-0.2 / kaffe / lookup.c < prev    next >
C/C++ Source or Header  |  1996-02-14  |  7KB  |  279 lines

  1. /*
  2.  * lookup.c
  3.  * Various lookup calls for resolving objects, methods, exceptions, etc.
  4.  *
  5.  * Copyright (c) 1996 Systems Architecture Research Centre,
  6.  *           City University, London, UK.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
  12.  */
  13.  
  14. #define DBG(s)
  15. #define FDBG(s)
  16. #define EDBG(s)
  17.  
  18. #include <stdio.h>
  19. #include <assert.h>
  20. #include "gtypes.h"
  21. #include "errors.h"
  22. #include "constants.h"
  23. #include "classMethod.h"
  24. #include "lookup.h"
  25. #include "exception.h"
  26. #include "thread.h"
  27.  
  28. extern strpair* initpair;
  29. extern methods* methodList;
  30. extern classes* ObjectClass;
  31.  
  32. /*
  33.  * Lookup a method reference and get the various interesting bits.
  34.  */
  35. void
  36. getMethodSignatureClass(constIndex idx, constants* pool, callInfo* call)
  37. {
  38.     constIndex ci;
  39.     constIndex ni;
  40.     constIndex nin;
  41.     constIndex nis;
  42.     char* str;
  43.     int i;
  44.     int inout[2];
  45.     createInfo cls;
  46.     strpair* pair;
  47.  
  48.     if (pool->tags[idx] != CONSTANT_Methodref &&
  49.         pool->tags[idx] != CONSTANT_InterfaceMethodref) {
  50. DBG(        printf("No Methodref found\n");                )
  51.         throwException(NoSuchMethodError);
  52.     }
  53.  
  54.     ni = METHODREF_NAMEANDTYPE(idx, pool);
  55.     if (pool->tags[ni] != CONSTANT_NameAndType) {
  56. DBG(        printf("No Methodref:NameAndType found\n");        )
  57.         throwException(NoSuchMethodError);
  58.     }
  59.     nin = NAMEANDTYPE_NAME(ni, pool);
  60.     if (pool->tags[nin] != CONSTANT_Utf8) {
  61. DBG(        printf("No Methodref:NameAndType:Utf8 found\n");    )
  62.         throwException(NoSuchMethodError);
  63.     }
  64.     nis = NAMEANDTYPE_SIGNATURE(ni, pool);
  65.     if (pool->tags[nis] != CONSTANT_Utf8) {
  66. DBG(        printf("No Methodref:NameAndType:Utf8 found\n");    )
  67.         throwException(NoSuchMethodError);
  68.     }
  69.  
  70.     ci = METHODREF_CLASS(idx, pool);
  71.     if (pool->tags[ci] != CONSTANT_Class) {
  72. DBG(        printf("No Methodref:Class found\n");            )
  73.         throwException(NoSuchMethodError);
  74.     }
  75.     getClass(ci, pool, &cls);
  76.  
  77. DBG(    printf("lookupMethodSignatureClass(%s,%s,%s)\n",
  78.         cls.class->name, pool->data[nin], pool->data[nis]);    )
  79.  
  80.     /*
  81.      * We now have a complete class and method signature.  We can
  82.      * Now work out some things we might need to know, like no. of
  83.      * arguments, address of function, etc.
  84.      */
  85.     countInsAndOuts((char*)pool->data[nis], &call->in, &call->out);
  86. DBG(    printf("in = %d, out = %d\n", call->in, call->out);        )
  87.     pair = lookupStringPair((char*)pool->data[nin], (char*)pool->data[nis]);
  88.     assert(pair != 0);
  89.     call->mtag = (int)pair;
  90.     call->offset = pair->hash % MAXMETHOD;
  91.     call->mtable = cls.class->mtable;
  92. }
  93.  
  94. void
  95. getClass(constIndex idx, constants* pool, createInfo* create)
  96. {
  97.     constIndex cs;
  98.     classes* class;
  99.     char* cname;
  100.  
  101.     if (pool->tags[idx] != CONSTANT_Class) {
  102. DBG(        printf("No Class found\n");                )
  103.         throwException(NoClassDefFoundError);
  104.     }
  105.  
  106.     cs = CLASS_NAME(idx, pool);
  107.     if (pool->tags[cs] != CONSTANT_Utf8) {
  108. DBG(        printf("No Class:Utf8 found\n");            )
  109.         throwException(NoClassDefFoundError);
  110.     }
  111.     cname = (char*)pool->data[cs];
  112.  
  113. DBG(    printf("Class name %s\n", cname);                )
  114.  
  115.     /* If an array, then treat as an array */
  116.     if (cname[0] == '[') {
  117.         class = lookupArray(cname);
  118.     }
  119.     else {
  120.         /* Lookup class */
  121.         class = lookupClass(cname);
  122.     }
  123.     if (class == 0) {
  124. DBG(        printf("Class %s not loaded.\n", cname);    )
  125.         throwException(NoClassDefFoundError);
  126.     }
  127.  
  128.     create->class = class;
  129. }
  130.  
  131. void
  132. getField(constIndex idx, bool isStatic, constants* pool, fieldInfo* fld)
  133. {
  134.     constIndex cs;
  135.     constIndex ci;
  136.     constIndex ni;
  137.     constIndex cis;
  138.     constIndex nin;
  139.     constIndex nis;
  140.     fields* field;
  141.  
  142.     if (pool->tags[idx] != CONSTANT_Fieldref) {
  143. FDBG(        printf("No Fieldref found\n");                )
  144.         throwException(NoSuchFieldError);
  145.     }
  146.  
  147.     ci = FIELDREF_CLASS(idx, pool);
  148.     if (pool->tags[ci] != CONSTANT_Class) {
  149. FDBG(        printf("No Methodref:Class found\n");            )
  150.         throwException(NoSuchFieldError);
  151.     }
  152.     ni = FIELDREF_NAMEANDTYPE(idx, pool);
  153.     if (pool->tags[ni] != CONSTANT_NameAndType) {
  154. FDBG(        printf("No Methodref:NameAndType found\n");        )
  155.         throwException(NoSuchFieldError);
  156.     }
  157.  
  158.     cis = CLASS_NAME(ci, pool);
  159.     if (pool->tags[cis] != CONSTANT_Utf8) {
  160. FDBG(        printf("No Methodref:Class:Utf8 found\n");        )
  161.         throwException(NoSuchFieldError);
  162.     }
  163.  
  164.     nin = NAMEANDTYPE_NAME(ni, pool);
  165.     if (pool->tags[nin] != CONSTANT_Utf8) {
  166. FDBG(        printf("No Methodref:NameAndType:Utf8 found\n");    )
  167.         throwException(NoSuchFieldError);
  168.     }
  169.     nis = NAMEANDTYPE_SIGNATURE(ni, pool);
  170.     if (pool->tags[nis] != CONSTANT_Utf8) {
  171. FDBG(        printf("No Methodref:NameAndType:Utf8 found\n");    )
  172.         throwException(NoSuchFieldError);
  173.     }
  174.  
  175. FDBG(    printf("*** getField(%s,%s,%s)\n",
  176.         pool->data[cis], pool->data[nin], pool->data[nis]);    )
  177.  
  178.     field = lookupClassField((char*)pool->data[cis], (char*)pool->data[nin], isStatic);
  179.     if (field == 0) {
  180. FDBG(        printf("Field not found\n");                )
  181.         throwException(NoSuchFieldError);
  182.     }
  183.  
  184.     fld->class = field->class;
  185.     fld->size = field->size;
  186.     fld->offset = field->offset;
  187.  
  188. FDBG(    printf("class=%s, classsize=%d, fldsize=%d, fldoffset=%d\n",
  189.         fld->class->name, fld->class->fsize,
  190.         fld->size, fld->offset);                )
  191. }
  192.  
  193. /*
  194.  * Lookup a method (and translate) in the specified class.
  195.  */
  196. void*
  197. findMethod(classes* class, strpair* pair)
  198. {
  199.     methods* mptr;
  200.     int r;
  201.  
  202.     classes* oclass;
  203.     methods* omethod;
  204.  
  205.     oclass = class;
  206.     omethod = 0;
  207.  
  208.     /*
  209.      * Lookup method - this could be alot more efficient but never mind.
  210.      * Also there is no attempt to honour PUBLIC, PRIVATE, etc.
  211.      */
  212.     for (; class != 0; class = class->superclass) {
  213.         for (mptr = class->methodList; mptr != 0; mptr = mptr->next) {
  214.             if (mptr->pair == pair) {
  215.                 /*
  216.                  * Generate code on demand.
  217.                  */
  218.                 if (mptr->ncode == 0) {
  219.                     intsDisable();
  220.                     translate(mptr);
  221.                     initClasses();
  222.                     intsRestore();
  223.                 }
  224.                 return (mptr->ncode);
  225.             }
  226.             omethod = mptr;
  227.         }
  228.     }
  229.     return (0);
  230. }
  231.  
  232. /*
  233.  * Find exception in method.
  234.  */
  235. void
  236. findExceptionInMethod(nativecode* pc, classes* class, exceptionInfo* info)
  237. {
  238.     methods* ptr;
  239.     exception* eptr;
  240.     int i;
  241.     classes* cptr;
  242.  
  243.     for (ptr = methodList; ptr != 0; ptr = ptr->exception_next) {
  244.         if (pc < ptr->ncode || pc >= ptr->ncode_end) {
  245.             continue;
  246.         }
  247. EDBG(        printf("Found method %s.%s%s\n", ptr->class->name,
  248.             ptr->pair->s1, ptr->pair->s2);            )
  249.         eptr = ptr->exception_table;
  250.  
  251. EDBG(        printf("Nr of exceptions = %d\n", ptr->exception_table_len); )
  252.  
  253.         /* Right method - look for exception */
  254.         for (i = 0; i < ptr->exception_table_len; i++) {
  255. EDBG(            printf("Exceptions %x (%x-%x)\n", pc, eptr[i].start_pc, eptr[i].end_pc); )
  256.             if (pc < (nativecode*)eptr[i].start_pc || pc > (nativecode*)eptr[i].end_pc) {
  257.                 continue;
  258.             }
  259. EDBG(            printf("Found exception 0x%x\n", eptr[i].handler_pc); )
  260.  
  261.             info->class = ptr->class;
  262.             info->handler = eptr[i].handler_pc;
  263.  
  264.             /* Found exception - is it right type */
  265.             if (eptr[i].catch_type == 0) {
  266.                 return;
  267.             }
  268.             for (cptr = class; cptr != 0; cptr = cptr->superclass) {
  269.                 if (cptr->name == eptr[i].catch_type) {
  270.                     return;
  271.                 }
  272.             }
  273.         }
  274.         break;
  275.     }
  276. EDBG(    printf("Exception not found.\n");                )
  277.     info->handler = 0;
  278. }
  279.